package org.dioib.practice.zero;

import io.netty.util.internal.StringUtil;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.dioib.practice.common.Result;
import org.dioib.practice.common.constant.StatusCode;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.util.*;
import java.util.stream.Collectors;

interface PrintLog{
//    default void prints(String s){
//        System.out.println(s);
//    }
    public void prints(String s);
}
@RestControllerAdvice
public class AdvancedMethod {


    public static void main(String[] args) {

        PrintLog log1 = new PrintLog() {
            public void prints(String s) {
                System.out.println(s);
            }
        };

        log1.prints("hello world!");

        PrintLog log2 = (s) -> System.out.println(s);
        log2.prints("hello world!");

        Thread th = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("hello thread!");
            }
        });

        th.start();

        Thread thread = new Thread(() -> System.out.println("hello thread!"));
        thread.start();

        String str1 = "hello world!";
        if (str1 != null) {
            System.out.println(str1.toUpperCase());
        }

        Optional.ofNullable(str1).map(String::toUpperCase).ifPresent(System.out::println);

        List<String> list = Arrays.asList("孙悟空", "唐僧", "猪八戒", "沙和尚", "白龙马", "猪大肠", "猪下水", "猪长老");
        for (String str : list) {
            System.out.println(str);
        }

        //当println的入参与循环元素的类型相同，直接简写如下System.out::println
        list.forEach(System.out::println);

        //lambda
        list.forEach(s -> System.out.println(s));

        //
        Collections.sort(list, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.compareTo(o2);
            }
        });

        //lambda  默认return o1.compareTo(o2)；
        Collections.sort(list, (o1, o2) -> o1.compareTo(o2));


        // 查找某字符开头
        List<String> list1 = new ArrayList<>();
        for (String str : list) {
            if (str.startsWith("猪")) {
                list1.add(str);
            }
            System.out.println("查找以某字母开头：" + list1.toString());
        }

        // 查找某字符开头与上面等价
        list1 = list.stream().filter(s -> s.startsWith("猪")).collect(Collectors.toList());

        List<Integer> list2 = new ArrayList<>();
        for (String s : list) {
            list2.add(s.length());
        }

        list2 = list.stream().map(s -> s.length()).collect(Collectors.toList());
        list2 = list.stream().map(s -> {
            return s.length();
        }).collect(Collectors.toList());

        // 转换成set
        Set<Integer> setInt = list.stream().map(s -> s.length()).collect(Collectors.toSet());
        setInt = list.stream().map(String::length).collect(Collectors.toSet());

        List<Integer> intList = Arrays.asList(1, 2, 3, 4, 5, 6);
        Integer sum = 0;
        for (Integer v : intList) {
            sum += v;
        }
        sum = intList.stream().reduce(0, (a, b) -> {
            return a + b;
        });
        sum = intList.stream().reduce(0, (a, b) -> a + b);
        Map<Integer, List<String>> groupBylenth = new HashMap<>();
        // 分组
        for (String s : list) {
            int length = s.length();
            if (!groupBylenth.containsKey(length)) {
                groupBylenth.put(s.length(), new ArrayList<>());
            }
            groupBylenth.get(length).add(s);
        }
        System.out.println(groupBylenth);

        Map<Integer, List<String>> groupBylenth2 = list.stream().collect(Collectors.groupingBy(String::length));

        System.out.println(groupBylenth2);

        List<String> listNew = Arrays.asList("孙悟空", "唐僧", "猪八戒", "沙和尚", "白龙马", "猪大肠", "猪下水", "猪长老");

        // list 内容找出包含猪的然后排序
        List<String> list3 = new ArrayList<>();
        for (String s : list) {
            if (s.startsWith("猪")) {
                list3.add("【" + s + "】");
            }
        }

        Collections.sort(list3);
        System.out.println("老的排序：\n" + list3);

        List<String> list4 = listNew.stream().filter(s -> s.startsWith("猪")).map(s -> {
            return "【" + s + "】";
        }).sorted().collect(Collectors.toList());
        System.out.println("新的排序：\n" + list4);


        List<String> listNew1 = Arrays.asList("sun wu kong", "tang seng", "zhu ba jie", "sha he shang ", "bai long ma", "zhu da chang", "bai yu tang", "sha bao liang");

        listNew1.forEach(System.out::println);
        listNew1.forEach(s -> {
            //TODO
        });


        for (String s : listNew1) {
            System.out.println(s);
        }

        // list 内容找出包含猪的然后排序
        List<String> list5 = new ArrayList<>();
        for (String s : listNew1) {
            if (s.contains(" ")) {
                list5.add(s.toUpperCase());
            }
        }

        //Collections.sort(list5);
        System.out.println("2老的排序：\n" + list5);

        List<String> list6 = listNew1.stream().filter(s -> s.contains(" ")).
                map(String::toUpperCase).sorted().collect(Collectors.toList());
        System.out.println("2新的排序：\n" + list6);

        //stream 常用方法
        List<String> ret = listNew1.stream().filter(s -> s.length() > 5)
                .distinct().sorted().skip(1).limit(2).collect(Collectors.toList());
        System.out.println(ret);


        List<Integer> listNew3 = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
        System.out.println("任意一个满足条件：" + listNew3.stream().anyMatch(v -> v > 8));//任意一个满足就返回true
        System.out.println("所都必须满足条件：" + listNew3.stream().allMatch(v -> v > 0));//所有都必须满足条件返回true
        System.out.println("所有都不满足条件：" + listNew3.stream().noneMatch(v -> v > 10));//所有都不满足条件返回true

        // find
        Optional<Integer> first = listNew3.stream().findFirst();
        Optional<Integer> any = listNew3.stream().findAny();
        Optional<Integer> min = listNew3.stream().min(Integer::compareTo);
        Optional<Integer> max = listNew3.stream().max(Integer::compareTo);
        System.out.println("first:" + first.orElse(null));
        System.out.println("any:" + any.orElse(null));
        System.out.println("min:" + min.orElse(null));
        System.out.println("max:" + max.orElse(null));

        //分组
        Map<Character, List<String>> groupListMap = listNew1.stream().collect(Collectors.groupingBy(s -> s.charAt(0)));
        System.out.println("分组方法1：\n" + groupListMap);

        Map<Boolean, List<Integer>> groupListMap1 = listNew3.stream().collect(Collectors.groupingBy(s -> s > 3));
        System.out.println("分组方法2：\n" + groupListMap1);
        //转换嵌套list
        List<List<Integer>> numbers = Arrays.asList(
                Arrays.asList(1, 2, 3),
                Arrays.asList(4, 5, 6),
                Arrays.asList(7, 8, 9),
                Arrays.asList(10, 11, 12)
        );
        List<Integer> flatList = numbers.stream().flatMap(List::stream).collect(Collectors.toList());
        System.out.println(flatList);
        List<Billing> billings = new ArrayList<>();
        billings.add(new Billing(new User(), 11.1));
        billings.add(new Billing(new User(), 12.1));
        billings.add(new Billing(new User(), 14.5));
        billings.add(new Billing(new User(), 121.1));

        Double total = billings.stream().mapToDouble(Billing::getAmount).reduce(0.0, Double::sum);
        System.out.println(total);
        //-----------------------------------------------------------------
        // User Dept
        Dept dept = new Dept();
        dept.setId(1);
        dept.setName("技术部");
        User user = new User();
        user.setId(1);
        user.setName("dingwell");
        user.setDept(dept);
        if (user != null) {
            if (user.getDept() != null) {
                String deptName = user.getDept().getName();
                if (StringUtil.isNullOrEmpty(deptName)) {
                    System.out.println("未指定部门");
                } else {
                    System.out.println(deptName);
                }
            } else {
                System.out.println("未指定部门");
            }
        }

        String msg = Optional.ofNullable(user).map(User::getDept).map(Dept::getName).
                filter(s -> !StringUtil.isNullOrEmpty(s)).orElse("未指定部门");

        System.out.println(msg);

        System.out.println("==============test()=================");
        System.out.println(test(null).getMessage());
        System.out.println(test(null).getCode());
        System.out.println(test(null).getData());

    }

    public static Result<User> test(User u) {
//        Dept dept = new Dept(2, "技术部");
//        User u = new User(1, "李强", dept);
        return Optional.ofNullable(u).map(Result::success)
                .orElse(Result.error(StatusCode.INTERNAL_ERROR));
    }

}

@Data
@AllArgsConstructor
@NoArgsConstructor
class Dept{
    private Integer id;
    private String name;
}

@Data
@AllArgsConstructor
@NoArgsConstructor
class User{
    private Integer id;
    private String name;
    private Dept dept;
}

@Data
@AllArgsConstructor
class Billing{
    private User user;
    private Double amount;
}